package com.abeo.absap;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.json.JSONObject;

import com.abeo.absap.adapter.CustomMasterItemAdaper;
import com.abeo.absap.utils.DirectionsJSONParser;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.PolylineOptions;

import android.app.Fragment;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Typeface;
import android.location.Location;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.TextView;

public class HomeFragment extends Fragment {

	private ListView mListView;
	private TextView mtextViewRouteCode;
	private TextView mtextViewRouteName;
	private TextView mtextViewVisited;
	private TextView mtextViewNotVisited;

	LocationManager mLocationManager;

	static final LatLng HAMBURG = new LatLng(53.558, 9.927);
	static final LatLng KIEL = new LatLng(53.551, 9.993);
	private GoogleMap map;

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		setRetainInstance(true);
		Typeface tf = Typeface.createFromAsset(getActivity().getAssets(),
				"fonts/myanmar3.ttf");
		View rootView = inflater.inflate(R.layout.fragment_home, container,
				false);
		this.mListView = (ListView) rootView.findViewById(R.id.listViewMessage);
		this.mtextViewRouteCode = (TextView) rootView
				.findViewById(R.id.textViewRouteCode);
		this.mtextViewRouteName = (TextView) rootView
				.findViewById(R.id.textViewRouteName);
		this.mtextViewVisited = (TextView) rootView
				.findViewById(R.id.textViewVisited);
		this.mtextViewNotVisited = (TextView) rootView
				.findViewById(R.id.textViewNotVisited);

		mtextViewRouteName.setTypeface(tf);

		this.mtextViewRouteCode.setText("R0000124");
		this.mtextViewRouteName
				.setText("အမှတ်(အက်စ်-၂)၊အခန်း(၀၀၁)၊မင်းရဲကျော်စွာဗီ");
		this.mtextViewVisited.setText("30");
		this.mtextViewNotVisited.setText("5");

		this.mListView
				.setAdapter(new CustomMasterItemAdaper(
						getActivity(),
						R.layout.message_list_item,
						new String[][] {
								{ "1",
										"အမှတ်(အက်စ်-၂)၊အခန်း(၀၀၁)၊မင်းရဲကျော်စွာဗီလာ၊တာမွေလေးရပ်ကွက" },
								{ "2",
										"အမှတ် (၃) ၊(၁၄၅) ၊ အရိုးကုန်းလမ်း ၊ တာမွေ ၊ ရန်ကုန်၊ မြန်မာ" },
								{ "3",
										"အမှတ်(အက်စ်-၂)၊အခန်း(၀၀၁)၊မင်းရဲကျော်စွာဗီလာ၊တာမွေလေးရပ်ကွက" },
								{ "4",
										"အမှတ်(အက်စ်-၂)၊အခန်း(၀၀၁)၊မင်းရဲကျော်စွာဗီလာ၊တာမွေလေးရပ်ကွက" },
								{ "5",
										"အမှတ်(၁/၀၀၂)၊ကျိုက်က္ကဆံအိမ်ယာ၊ကျိုက်က္ကဆံလမ်း၊တာမွေကြီး(ခ)ရပ်ကွက" },
								{ "6",
										"အမှတ်(၁/၀၀၂)၊ကျိုက်က္ကဆံအိမ်ယာ၊ကျိုက်က္ကဆံလမ်း၊တာမွေကြီး(ခ)ရပ်ကွက" },
								{ "7",
										"အမှတ် (၅၂) ၊ဗျိုင်းရေအိုးစဉ်လမ်း ၊ တာမွေ ၊ ရန်ကုန်၊ မြန်မာ" },
								{ "8",
										"အမှတ် (၃) ၊(၁၄၅) ၊ အရိုးကုန်းလမ်း ၊ တာမွေ ၊ ရန်ကုန်၊ မြန်မာ" },
								{ "9",
										"အမှတ် (၃) ၊(၁၄၅) ၊ အရိုးကုန်းလမ်း ၊ တာမွေ ၊ ရန်ကုန်၊ မြန်မာ" },
								{ "10",
										"အမှတ် (၅၂) ၊ဗျိုင်းရေအိုးစဉ်လမ်း ၊ တာမွေ ၊ ရန်ကုန်၊ မြန်မာ" } }));

		map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map))
				.getMap();
		/*
		 * Marker hamburg = map.addMarker(new MarkerOptions().position(HAMBURG)
		 * .title("Hamburg")); Marker kiel = map.addMarker(new MarkerOptions()
		 * .position(KIEL) .title("Kiel") .snippet("Kiel is cool")
		 * .icon(BitmapDescriptorFactory
		 * .fromResource(R.drawable.ic_launcher)));
		 * 
		 * // Move the camera instantly to hamburg with a zoom of 15.
		 * map.moveCamera(CameraUpdateFactory.newLatLngZoom(HAMBURG, 15));
		 * 
		 * // Zoom in, animating the camera.
		 * map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);
		 */

		// map.setMyLocationEnabled(true);

		mLocationManager = (LocationManager) getActivity().getSystemService(
				getActivity().LOCATION_SERVICE);
		// Criteria criteria = new Criteria();
		// Location location = locationManager
		// .getLastKnownLocation(locationManager.getBestProvider(criteria,
		// false));

		// Location location =
		// locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);

		// Location location1 = map.getMyLocation();
		// if (location != null) {

		/*
		 * Criteria criteria = new Criteria();
		 * criteria.setAccuracy(Criteria.ACCURACY_COARSE); // Finds a provider
		 * that matches the criteria String provider =
		 * locationManager.getBestProvider(criteria, true); // Use the provider
		 * to get the last known location Location location =
		 * locationManager.getLastKnownLocation(provider);
		 * 
		 * LatLng myLocation = new LatLng(location.getLatitude(),
		 * location.getLongitude()); Marker myL = map.addMarker(new
		 * MarkerOptions() .position(myLocation) .title("Your Location"));
		 * map.animateCamera(CameraUpdateFactory.newLatLngZoom(myLocation, 13));
		 */
		// }
		focusMapOnCurrentLocation();
		// LoadDirection();

		// Getting URL to the Google Directions API
		String url = getDirectionsUrl(new LatLng(10.7891304, 106.700646),
				new LatLng(10.7822061, 106.6965691));
		if (isOnline()) {
			DownloadTask downloadTask = new DownloadTask();

			// Start downloading json data from Google Directions API
			downloadTask.execute(url);

			map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(
					10.7891304, 106.700646), 15));
		}

		return rootView;
	}

	private void LoadDirection() {

		// Instantiating the class MarkerOptions to plot marker on the map
		MarkerOptions markerOptions1 = new MarkerOptions();

		// Setting latitude and longitude of the marker position
		markerOptions1.position(new LatLng(37.35, -122.0));

		// Setting titile of the infowindow of the marker
		markerOptions1.title("Position 1");

		MarkerOptions markerOptions2 = new MarkerOptions();

		// Setting latitude and longitude of the marker position
		markerOptions2.position(new LatLng(37.45, -122.0));

		// Setting titile of the infowindow of the marker
		markerOptions2.title("Position 2");

		MarkerOptions markerOptions3 = new MarkerOptions();

		// Setting latitude and longitude of the marker position
		markerOptions3.position(new LatLng(37.45, -122.2));

		// Setting titile of the infowindow of the marker
		markerOptions3.title("Position 3");

		MarkerOptions markerOptions4 = new MarkerOptions();

		// Setting latitude and longitude of the marker position
		markerOptions4.position(new LatLng(37.35, -122.2));

		// Setting titile of the infowindow of the marker
		markerOptions4.title("Position 4");

		// Instantiating the class PolylineOptions to plot polyline in the map
		PolylineOptions polylineOptions = new PolylineOptions();

		// Setting the color of the polyline
		polylineOptions.color(Color.RED);

		// Setting the width of the polyline
		polylineOptions.width(3);

		// Adding the taped point to the ArrayList
		polylineOptions.add(new LatLng(37.35, -122.0))
				.add(new LatLng(37.45, -122.0)) // North of the previous point,
												// but at the same longitude
				.add(new LatLng(37.45, -122.2)) // Same latitude, and 30km to
												// the west
				.add(new LatLng(37.35, -122.2)) // Same longitude, and 16km to
												// the south
				.add(new LatLng(37.35, -122.0));

		// Setting points of polyline

		// Adding the polyline to the map
		map.addPolyline(polylineOptions);

		// Adding the marker to the map
		map.addMarker(markerOptions1);
		map.addMarker(markerOptions2);
		map.addMarker(markerOptions3);
		map.addMarker(markerOptions4);

		map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(37.35,
				-122.0), 10));
	}

	private Location getCurrentLocation() {
		// Defining current location by the best providers, that availble at
		// runtime on current device;
		Location location = null;
		String[] providers = new String[3];
		providers[0] = LocationManager.GPS_PROVIDER;
		providers[1] = LocationManager.NETWORK_PROVIDER;
		providers[2] = LocationManager.PASSIVE_PROVIDER;

		for (String provider : providers) {
			if (!mLocationManager.isProviderEnabled(provider))
				continue;
			// mLocationManager.requestLocationUpdates(provider,
			// MIN_TIME_BW_UPDATES, MIN_DISTANCE_UPDATES, this);
			if (mLocationManager != null) {
				location = mLocationManager.getLastKnownLocation(provider);
				if (location != null) {
					break;
				}
			}
		}
		return location;
	}

	private void focusMapOnCurrentLocation() {
		final int DURATIONMS_CONST = 2000;
		final int ZOOM_ANIM_CAMERA_CONST = 15;
		final int ZOOM_MOVE_CAMERA_CONST = 20;

		// Set focus on current location on google map;

		Location location = getCurrentLocation();
		if (location != null) {
			double lat = location.getLatitude();
			double log = location.getLongitude();
			LatLng latLng = new LatLng(lat, log);
			Marker myL = map.addMarker(new MarkerOptions().position(latLng)
					.title("Your Location"));

			map.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng,
					ZOOM_MOVE_CAMERA_CONST));
			map.animateCamera(
					CameraUpdateFactory.zoomTo(ZOOM_ANIM_CAMERA_CONST),
					DURATIONMS_CONST, null);
		}
	}

	@Override
	public void onDestroyView() {
		super.onDestroyView();
		try {
			MapFragment fragment = (MapFragment) getActivity()
					.getFragmentManager().findFragmentById(R.id.map);
			if (fragment != null)
				getFragmentManager().beginTransaction().remove(fragment)
						.commit();

		} catch (IllegalStateException e) {
		}
	}

	private String getDirectionsUrl(LatLng origin, LatLng dest) {

		// Origin of route
		String str_origin = "origin=" + origin.latitude + ","
				+ origin.longitude;

		// Destination of route
		String str_dest = "destination=" + dest.latitude + "," + dest.longitude;

		// Sensor enabled
		String sensor = "sensor=false";

		// Building the parameters to the web service
		String parameters = str_origin + "&" + str_dest + "&" + sensor;

		// Output format
		String output = "json";

		// Building the url to the web service
		String url = "https://maps.googleapis.com/maps/api/directions/"
				+ output + "?" + parameters;

		return url;
	}

	/** A method to download json data from url */
	private String downloadUrl(String strUrl) throws IOException {
		String data = "";
		InputStream iStream = null;
		HttpURLConnection urlConnection = null;
		try {
			URL url = new URL(strUrl);

			// Creating an http connection to communicate with url
			urlConnection = (HttpURLConnection) url.openConnection();

			// Connecting to url
			urlConnection.connect();

			// Reading data from url
			iStream = urlConnection.getInputStream();

			BufferedReader br = new BufferedReader(new InputStreamReader(
					iStream));

			StringBuffer sb = new StringBuffer();

			String line = "";
			while ((line = br.readLine()) != null) {
				sb.append(line);
			}

			data = sb.toString();

			br.close();

		} catch (Exception e) {
			Log.d("Exception while downloading url", e.toString());
		} finally {
			iStream.close();
			urlConnection.disconnect();
		}
		return data;
	}

	// Fetches data from url passed
	private class DownloadTask extends AsyncTask<String, Void, String> {

		// Downloading data in non-ui thread
		@Override
		protected String doInBackground(String... url) {

			// For storing data from web service
			String data = "";

			try {
				// Fetching the data from web service
				data = downloadUrl(url[0]);
			} catch (Exception e) {
				Log.d("Background Task", e.toString());
			}
			return data;
		}

		// Executes in UI thread, after the execution of
		// doInBackground()
		@Override
		protected void onPostExecute(String result) {
			super.onPostExecute(result);

			ParserTask parserTask = new ParserTask();

			// Invokes the thread for parsing the JSON data
			parserTask.execute(result);
		}
	}

	/** A class to parse the Google Places in JSON format */
	private class ParserTask extends
			AsyncTask<String, Integer, List<List<HashMap<String, String>>>> {

		// Parsing the data in non-ui thread
		@Override
		protected List<List<HashMap<String, String>>> doInBackground(
				String... jsonData) {

			JSONObject jObject;
			List<List<HashMap<String, String>>> routes = null;

			try {
				jObject = new JSONObject(jsonData[0]);
				DirectionsJSONParser parser = new DirectionsJSONParser();

				// Starts parsing data
				routes = parser.parse(jObject);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return routes;
		}

		// Executes in UI thread, after the parsing process
		@Override
		protected void onPostExecute(List<List<HashMap<String, String>>> result) {
			ArrayList<LatLng> points = null;
			PolylineOptions lineOptions = null;
			MarkerOptions markerOptions = new MarkerOptions();
			MarkerOptions markerOptions1 = new MarkerOptions();
			MarkerOptions markerOptions2 = new MarkerOptions();
			// Traversing through all the routes
			for (int i = 0; i < result.size(); i++) {
				points = new ArrayList<LatLng>();
				lineOptions = new PolylineOptions();

				// Fetching i-th route
				List<HashMap<String, String>> path = result.get(i);

				// Fetching all the points in i-th route
				for (int j = 0; j < path.size(); j++) {
					HashMap<String, String> point = path.get(j);

					double lat = Double.parseDouble(point.get("lat"));
					double lng = Double.parseDouble(point.get("lng"));
					LatLng position = new LatLng(lat, lng);

					points.add(position);
				}

				// Adding all the points in the route to LineOptions
				lineOptions.addAll(points);
				lineOptions.width(2);
				lineOptions.color(Color.RED);
			}

			// Drawing polyline in the Google Map for the i-th route

			// Setting latitude and longitude of the marker position
			markerOptions1.position(new LatLng(10.7891304, 106.700646));

			// Setting titile of the infowindow of the marker
			markerOptions1.title("From here");

			// Setting latitude and longitude of the marker position
			markerOptions2.position(new LatLng(10.7822061, 106.6965691));

			markerOptions2.title("To here");

			map.addMarker(markerOptions1);
			map.addMarker(markerOptions2);
			map.addPolyline(lineOptions);
		}
	}

	public boolean isOnline() {
		ConnectivityManager cm = (ConnectivityManager) getActivity()
				.getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo netInfo = cm.getActiveNetworkInfo();
		if (netInfo != null && netInfo.isConnectedOrConnecting()) {
			return true;
		}
		return false;
	}
}
